<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 17 Cookies | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.20 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 17 Cookies | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 17 Cookies | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-09-04" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="custom-inputs.html"/>
<link rel="next" href="widgets-with-shiny.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/accessible-code-block/empty-anchor.js"></script>
<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>
<script src="libs/viz/viz.js"></script>
<link href="libs/DiagrammeR-styles/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding/grViz.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="overview.html"><a href="overview.html"><i class="fa fa-check"></i><b>1</b> Overview</a>
<ul>
<li class="chapter" data-level="1.1" data-path="overview.html"><a href="overview.html#rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="overview.html"><a href="overview.html#methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a>
<ul>
<li class="chapter" data-level="1.2.1" data-path="overview.html"><a href="overview.html#v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="overview.html"><a href="overview.html#htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
<li class="chapter" data-level="1.2.4" data-path="overview.html"><a href="overview.html#bubble"><i class="fa fa-check"></i><b>1.2.4</b> bubble</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="overview.html"><a href="overview.html#methods-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a>
<ul>
<li class="chapter" data-level="1.3.1" data-path="overview.html"><a href="overview.html#reactr"><i class="fa fa-check"></i><b>1.3.1</b> reactR</a></li>
<li class="chapter" data-level="1.3.2" data-path="overview.html"><a href="overview.html#r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a>
<ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#r-package-development"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a>
<ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#creating-a-package"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#build-load-and-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#json"><i class="fa fa-check"></i><b>2.2</b> JSON</a>
<ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#tabular-data"><i class="fa fa-check"></i><b>2.2.2</b> Tabular data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a>
<ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#developer-tools"><i class="fa fa-check"></i><b>2.3.1</b> Developer tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#variable-declaration-and-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable declaration and scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#document-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document object model</a></li>
</ul></li>
<li class="chapter" data-level="2.4" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>2.4</b> Shiny</a>
<ul>
<li class="chapter" data-level="2.4.1" data-path="prerequisites.html"><a href="prerequisites.html#htmltools"><i class="fa fa-check"></i><b>2.4.1</b> Htmltools</a></li>
<li class="chapter" data-level="2.4.2" data-path="prerequisites.html"><a href="prerequisites.html#static-files"><i class="fa fa-check"></i><b>2.4.2</b> Static files</a></li>
<li class="chapter" data-level="2.4.3" data-path="prerequisites.html"><a href="prerequisites.html#dependencies-pros-and-cons"><i class="fa fa-check"></i><b>2.4.3</b> Dependencies Pros and Cons</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html"><i class="fa fa-check"></i><b>3</b> Introduction to Widgets</a>
<ul>
<li class="chapter" data-level="3.1" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#plotly-package"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#dt-package"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html"><i class="fa fa-check"></i><b>4</b> Basics of Building Widgets</a>
<ul>
<li class="chapter" data-level="4.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#candidate-libraries"><i class="fa fa-check"></i><b>4.1</b> Candidate Libraries</a>
<ul>
<li class="chapter" data-level="4.1.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#plotly.js"><i class="fa fa-check"></i><b>4.1.1</b> Plotly.js</a></li>
<li class="chapter" data-level="4.1.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#highchart.js"><i class="fa fa-check"></i><b>4.1.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.1.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#chart.js"><i class="fa fa-check"></i><b>4.1.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>4.2</b> How it works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="your-first-widget.html"><a href="your-first-widget.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a>
<ul>
<li class="chapter" data-level="5.1" data-path="your-first-widget.html"><a href="your-first-widget.html#the-htmlwidgets-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Htmlwidgets Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="your-first-widget.html"><a href="your-first-widget.html#the-html-output"><i class="fa fa-check"></i><b>5.2</b> The HTML Output</a></li>
<li class="chapter" data-level="5.3" data-path="your-first-widget.html"><a href="your-first-widget.html#htmlwidgets-javascript-files"><i class="fa fa-check"></i><b>5.3</b> Htmlwidgets JavaScript Files</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a>
<ul>
<li class="chapter" data-level="6.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-dependencies"><i class="fa fa-check"></i><b>6.1</b> Peity.js Dependencies</a></li>
<li class="chapter" data-level="6.2" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-implementation"><i class="fa fa-check"></i><b>6.2</b> Peity.js Implementation</a></li>
<li class="chapter" data-level="6.3" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-html-element"><i class="fa fa-check"></i><b>6.3</b> Peity.js HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="the-full-monty.html"><a href="the-full-monty.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a>
<ul>
<li class="chapter" data-level="7.1" data-path="the-full-monty.html"><a href="the-full-monty.html#gio.js-dependencies"><i class="fa fa-check"></i><b>7.1</b> Gio.js Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="the-full-monty.html"><a href="the-full-monty.html#gio.js-javascript"><i class="fa fa-check"></i><b>7.2</b> Gio.js JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="the-full-monty.html"><a href="the-full-monty.html#transforming-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a>
<ul>
<li class="chapter" data-level="7.4.1" data-path="the-full-monty.html"><a href="the-full-monty.html#using-javascript"><i class="fa fa-check"></i><b>7.4.1</b> Using JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="the-full-monty.html"><a href="the-full-monty.html#using-r"><i class="fa fa-check"></i><b>7.4.2</b> Using R</a></li>
<li class="chapter" data-level="7.4.3" data-path="the-full-monty.html"><a href="the-full-monty.html#pros-cons"><i class="fa fa-check"></i><b>7.4.3</b> Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="the-full-monty.html"><a href="the-full-monty.html#on-print-method"><i class="fa fa-check"></i><b>7.5</b> On Print Method</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="advanced-topics.html"><a href="advanced-topics.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a>
<ul>
<li class="chapter" data-level="8.1" data-path="advanced-topics.html"><a href="advanced-topics.html#shared-variables"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a>
<ul>
<li class="chapter" data-level="8.1.1" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="advanced-topics.html"><a href="advanced-topics.html#resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="advanced-topics.html"><a href="advanced-topics.html#pre-render-hooks-security"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks &amp; Security</a></li>
<li class="chapter" data-level="8.4" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="advanced-topics.html"><a href="advanced-topics.html#prepend-append-content"><i class="fa fa-check"></i><b>8.5</b> Prepend &amp; Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="advanced-topics.html"><a href="advanced-topics.html#dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="advanced-topics.html"><a href="advanced-topics.html#compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="advanced-topics.html"><a href="advanced-topics.html#unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="linking-widgets.html"><a href="linking-widgets.html"><i class="fa fa-check"></i><b>9</b> Linking Widgets</a>
<ul>
<li class="chapter" data-level="9.1" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-examples"><i class="fa fa-check"></i><b>9.1</b> Crosstalk examples</a></li>
<li class="chapter" data-level="9.2" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-requirements"><i class="fa fa-check"></i><b>9.2</b> Crosstalk requirements</a></li>
<li class="chapter" data-level="9.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>9.3</b> How it works</a></li>
<li class="chapter" data-level="9.4" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-with-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with gio</a></li>
<li class="chapter" data-level="9.5" data-path="linking-widgets.html"><a href="linking-widgets.html#adapt-the-r-code"><i class="fa fa-check"></i><b>9.5</b> Adapt the R code</a></li>
<li class="chapter" data-level="9.6" data-path="linking-widgets.html"><a href="linking-widgets.html#change-the-javascript-code"><i class="fa fa-check"></i><b>9.6</b> Change the JavaScript code</a>
<ul>
<li class="chapter" data-level="9.6.1" data-path="linking-widgets.html"><a href="linking-widgets.html#send-selected-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send selected keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="linking-widgets.html"><a href="linking-widgets.html#set-selected-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set selected keys</a></li>
<li class="chapter" data-level="9.6.3" data-path="linking-widgets.html"><a href="linking-widgets.html#recap-javascript-code"><i class="fa fa-check"></i><b>9.6.3</b> Recap JavaScript code</a></li>
</ul></li>
<li class="chapter" data-level="9.7" data-path="linking-widgets.html"><a href="linking-widgets.html#using-crosstalk-with-gio"><i class="fa fa-check"></i><b>9.7</b> Using crosstalk with gio</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="final-revisions.html"><a href="final-revisions.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a>
<ul>
<li class="chapter" data-level="10.1" data-path="final-revisions.html"><a href="final-revisions.html#htmlwidgets-data"><i class="fa fa-check"></i><b>10.1</b> Htmlwidgets &amp; Data</a></li>
<li class="chapter" data-level="10.2" data-path="final-revisions.html"><a href="final-revisions.html#plethora-of-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of Options</a></li>
<li class="chapter" data-level="10.3" data-path="final-revisions.html"><a href="final-revisions.html#interface-design"><i class="fa fa-check"></i><b>10.3</b> Interface Design</a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="excercise-ploty.html"><a href="excercise-ploty.html"><i class="fa fa-check"></i><b>11</b> Excercise - Ploty</a>
<ul>
<li class="chapter" data-level="11.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#discover-plotly"><i class="fa fa-check"></i><b>11.1</b> Discover Plotly</a></li>
<li class="chapter" data-level="11.2" data-path="excercise-ploty.html"><a href="excercise-ploty.html#basics-of-plotly"><i class="fa fa-check"></i><b>11.2</b> Basics of Plotly</a></li>
<li class="chapter" data-level="11.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#plotly.js-to-r"><i class="fa fa-check"></i><b>11.3</b> Plotly.js to R</a></li>
<li class="chapter" data-level="11.4" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-plotly.js"><i class="fa fa-check"></i><b>11.4</b> R to Plotly.js</a></li>
<li class="chapter" data-level="11.5" data-path="excercise-ploty.html"><a href="excercise-ploty.html#size-resize-plotly.js"><i class="fa fa-check"></i><b>11.5</b> Size &amp; Resize Plotly.js</a></li>
<li class="chapter" data-level="11.6" data-path="excercise-ploty.html"><a href="excercise-ploty.html#performance-security-with-plotly.js"><i class="fa fa-check"></i><b>11.6</b> Performance &amp; Security with Plotly.js</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="12" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html"><i class="fa fa-check"></i><b>12</b> Introduction to Shiny</a>
<ul>
<li class="chapter" data-level="12.1" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#websocket-shiny"><i class="fa fa-check"></i><b>12.1</b> Websocket &amp; Shiny</a></li>
<li class="chapter" data-level="12.2" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-an-example"><i class="fa fa-check"></i><b>12.2</b> Alerts, An Example</a></li>
<li class="chapter" data-level="12.3" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-r-to-js"><i class="fa fa-check"></i><b>12.3</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.4" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-js-to-r"><i class="fa fa-check"></i><b>12.4</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.5" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-deserialise"><i class="fa fa-check"></i><b>12.5</b> Deserialise</a></li>
</ul></li>
<li class="chapter" data-level="13" data-path="a-complete-integration.html"><a href="a-complete-integration.html"><i class="fa fa-check"></i><b>13</b> A Complete Integration</a>
<ul>
<li class="chapter" data-level="13.1" data-path="a-complete-integration.html"><a href="a-complete-integration.html#serialisation"><i class="fa fa-check"></i><b>13.1</b> Serialisation</a></li>
<li class="chapter" data-level="13.2" data-path="a-complete-integration.html"><a href="a-complete-integration.html#events-callbacks"><i class="fa fa-check"></i><b>13.2</b> Events &amp; Callbacks</a></li>
<li class="chapter" data-level="13.3" data-path="a-complete-integration.html"><a href="a-complete-integration.html#as-a-package"><i class="fa fa-check"></i><b>13.3</b> As a Package</a>
<ul>
<li class="chapter" data-level="13.3.1" data-path="advanced-topics.html"><a href="advanced-topics.html#dependencies"><i class="fa fa-check"></i><b>13.3.1</b> Dependencies</a></li>
<li class="chapter" data-level="13.3.2" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>13.3.2</b> R Code</a></li>
<li class="chapter" data-level="13.3.3" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>13.3.3</b> JavaScript Code</a></li>
<li class="chapter" data-level="13.3.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>13.3.4</b> Input Handler</a></li>
<li class="chapter" data-level="13.3.5" data-path="a-complete-integration.html"><a href="a-complete-integration.html#wrapping-up"><i class="fa fa-check"></i><b>13.3.5</b> Wrapping up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="14" data-path="tips-tricks.html"><a href="tips-tricks.html"><i class="fa fa-check"></i><b>14</b> Tips &amp; Tricks</a>
<ul>
<li class="chapter" data-level="14.1" data-path="tips-tricks.html"><a href="tips-tricks.html#shiny-events"><i class="fa fa-check"></i><b>14.1</b> Shiny Events</a></li>
<li class="chapter" data-level="14.2" data-path="tips-tricks.html"><a href="tips-tricks.html#table-buttons"><i class="fa fa-check"></i><b>14.2</b> Table Buttons</a></li>
<li class="chapter" data-level="14.3" data-path="tips-tricks.html"><a href="tips-tricks.html#jquery---toggle"><i class="fa fa-check"></i><b>14.3</b> jQuery - Toggle</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="custom-outputs.html"><a href="custom-outputs.html"><i class="fa fa-check"></i><b>15</b> Custom Outputs</a>
<ul>
<li class="chapter" data-level="15.1" data-path="custom-outputs.html"><a href="custom-outputs.html#custom-outputs-inner-workings"><i class="fa fa-check"></i><b>15.1</b> Custom Outputs Inner-workings</a></li>
<li class="chapter" data-level="15.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup-custom-output"><i class="fa fa-check"></i><b>15.2</b> Setup Custom Output</a></li>
<li class="chapter" data-level="15.3" data-path="custom-outputs.html"><a href="custom-outputs.html#output-r-function"><i class="fa fa-check"></i><b>15.3</b> Output R Function</a></li>
<li class="chapter" data-level="15.4" data-path="custom-outputs.html"><a href="custom-outputs.html#generate-output-html"><i class="fa fa-check"></i><b>15.4</b> Generate Output HTML</a></li>
<li class="chapter" data-level="15.5" data-path="custom-outputs.html"><a href="custom-outputs.html#output-renderer"><i class="fa fa-check"></i><b>15.5</b> Output Renderer</a></li>
<li class="chapter" data-level="15.6" data-path="custom-outputs.html"><a href="custom-outputs.html#javascript-output-binding"><i class="fa fa-check"></i><b>15.6</b> JavaScript Output Binding</a>
<ul>
<li class="chapter" data-level="15.6.1" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-title"><i class="fa fa-check"></i><b>15.6.1</b> Boxxy title</a></li>
<li class="chapter" data-level="15.6.2" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-value"><i class="fa fa-check"></i><b>15.6.2</b> Boxxy value</a></li>
<li class="chapter" data-level="15.6.3" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-background-color"><i class="fa fa-check"></i><b>15.6.3</b> Boxxy Background Color</a></li>
<li class="chapter" data-level="15.6.4" data-path="custom-outputs.html"><a href="custom-outputs.html#register-the-output-binding"><i class="fa fa-check"></i><b>15.6.4</b> Register the Output Binding</a></li>
</ul></li>
<li class="chapter" data-level="15.7" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-usage"><i class="fa fa-check"></i><b>15.7</b> Boxxy Usage</a></li>
<li class="chapter" data-level="15.8" data-path="custom-outputs.html"><a href="custom-outputs.html#injecting-dependencies"><i class="fa fa-check"></i><b>15.8</b> Injecting Dependencies</a></li>
<li class="chapter" data-level="15.9" data-path="custom-outputs.html"><a href="custom-outputs.html#preprocessing-custom-outputs"><i class="fa fa-check"></i><b>15.9</b> Preprocessing Custom Outputs</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="custom-inputs.html"><a href="custom-inputs.html"><i class="fa fa-check"></i><b>16</b> Custom Inputs</a>
<ul>
<li class="chapter" data-level="16.1" data-path="custom-inputs.html"><a href="custom-inputs.html#setup-custom-input"><i class="fa fa-check"></i><b>16.1</b> Setup Custom Input</a></li>
<li class="chapter" data-level="16.2" data-path="custom-inputs.html"><a href="custom-inputs.html#switch-input-html-style"><i class="fa fa-check"></i><b>16.2</b> Switch Input HTML &amp; Style</a></li>
<li class="chapter" data-level="16.3" data-path="custom-inputs.html"><a href="custom-inputs.html#generate-input-html"><i class="fa fa-check"></i><b>16.3</b> Generate Input HTML</a></li>
<li class="chapter" data-level="16.4" data-path="custom-inputs.html"><a href="custom-inputs.html#javascript-input-binding"><i class="fa fa-check"></i><b>16.4</b> JavaScript Input Binding</a>
<ul>
<li class="chapter" data-level="16.4.1" data-path="custom-inputs.html"><a href="custom-inputs.html#find-inputs"><i class="fa fa-check"></i><b>16.4.1</b> Find Inputs</a></li>
<li class="chapter" data-level="16.4.2" data-path="custom-inputs.html"><a href="custom-inputs.html#get-input-id"><i class="fa fa-check"></i><b>16.4.2</b> Get Input Id</a></li>
<li class="chapter" data-level="16.4.3" data-path="custom-inputs.html"><a href="custom-inputs.html#get-input-value"><i class="fa fa-check"></i><b>16.4.3</b> Get Input Value</a></li>
<li class="chapter" data-level="16.4.4" data-path="custom-inputs.html"><a href="custom-inputs.html#set-input-value"><i class="fa fa-check"></i><b>16.4.4</b> Set Input Value</a></li>
<li class="chapter" data-level="16.4.5" data-path="custom-inputs.html"><a href="custom-inputs.html#receive-input-messages"><i class="fa fa-check"></i><b>16.4.5</b> Receive Input Messages</a></li>
<li class="chapter" data-level="16.4.6" data-path="custom-inputs.html"><a href="custom-inputs.html#subscribe-unsubscribe-inputs"><i class="fa fa-check"></i><b>16.4.6</b> Subscribe &amp; Unsubscribe Inputs</a></li>
<li class="chapter" data-level="16.4.7" data-path="custom-inputs.html"><a href="custom-inputs.html#input-rate-policy"><i class="fa fa-check"></i><b>16.4.7</b> Input Rate Policy</a></li>
<li class="chapter" data-level="16.4.8" data-path="custom-inputs.html"><a href="custom-inputs.html#registering-the-input"><i class="fa fa-check"></i><b>16.4.8</b> Registering the Input</a></li>
</ul></li>
<li class="chapter" data-level="16.5" data-path="custom-inputs.html"><a href="custom-inputs.html#update-input"><i class="fa fa-check"></i><b>16.5</b> Update Input</a></li>
<li class="chapter" data-level="16.6" data-path="custom-inputs.html"><a href="custom-inputs.html#exercise"><i class="fa fa-check"></i><b>16.6</b> Exercise</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="cookies.html"><a href="cookies.html"><i class="fa fa-check"></i><b>17</b> Cookies</a>
<ul>
<li class="chapter" data-level="17.1" data-path="cookies.html"><a href="cookies.html#discover-js-cookie"><i class="fa fa-check"></i><b>17.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="17.2" data-path="cookies.html"><a href="cookies.html#setup-cookies-project"><i class="fa fa-check"></i><b>17.2</b> Setup Cookies Project</a></li>
<li class="chapter" data-level="17.3" data-path="cookies.html"><a href="cookies.html#javascript-cookies"><i class="fa fa-check"></i><b>17.3</b> JavaScript Cookies</a></li>
<li class="chapter" data-level="17.4" data-path="cookies.html"><a href="cookies.html#r-code-for-cookies"><i class="fa fa-check"></i><b>17.4</b> R Code for Cookies</a></li>
</ul></li>
<li class="chapter" data-level="18" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html"><i class="fa fa-check"></i><b>18</b> Widgets with Shiny</a>
<ul>
<li class="chapter" data-level="18.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#widgets-to-r"><i class="fa fa-check"></i><b>18.1</b> Widgets to R</a></li>
<li class="chapter" data-level="18.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#input-handlers-for-widgets"><i class="fa fa-check"></i><b>18.2</b> Input Handlers for Widgets</a></li>
<li class="chapter" data-level="18.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#r-to-widgets"><i class="fa fa-check"></i><b>18.3</b> R to Widgets</a>
<ul>
<li class="chapter" data-level="18.3.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#send-data-from-widgets"><i class="fa fa-check"></i><b>18.3.1</b> Send Data from Widgets</a></li>
<li class="chapter" data-level="18.3.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#retrieve-widget-instance"><i class="fa fa-check"></i><b>18.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="18.3.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#handle-data"><i class="fa fa-check"></i><b>18.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="18.4" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#proxy-function"><i class="fa fa-check"></i><b>18.4</b> Proxy Function</a></li>
<li class="chapter" data-level="18.5" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#clear-data"><i class="fa fa-check"></i><b>18.5</b> Clear Data</a></li>
<li class="chapter" data-level="18.6" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#update-the-widget"><i class="fa fa-check"></i><b>18.6</b> Update the Widget</a></li>
</ul></li>
<li class="part"><span><b>IV Interactive Documents</b></span></li>
<li class="chapter" data-level="19" data-path="introduction-to-rmarkdown.html"><a href="introduction-to-rmarkdown.html"><i class="fa fa-check"></i><b>19</b> Introduction to Rmarkdown</a></li>
<li class="part"><span><b>V JavaScript for Computations</b></span></li>
<li class="chapter" data-level="20" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>20</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="20.1" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i><b>20.1</b> Installation</a></li>
<li class="chapter" data-level="20.2" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i><b>20.2</b> Basics</a></li>
<li class="chapter" data-level="20.3" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i><b>20.3</b> External Libraries</a></li>
<li class="chapter" data-level="20.4" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i><b>20.4</b> With Npm</a></li>
<li class="chapter" data-level="20.5" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i><b>20.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html"><i class="fa fa-check"></i><b>21</b> Exercise - Machine Learning</a>
<ul>
<li class="chapter" data-level="21.1" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html#dependency"><i class="fa fa-check"></i><b>21.1</b> Dependency</a></li>
<li class="chapter" data-level="21.2" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html#simple-regression"><i class="fa fa-check"></i><b>21.2</b> Simple Regression</a></li>
</ul></li>
<li class="part"><span><b>VI Examples</b></span></li>
<li class="chapter" data-level="22" data-path="image-classifier.html"><a href="image-classifier.html"><i class="fa fa-check"></i><b>22</b> Image Classifier</a>
<ul>
<li class="chapter" data-level="22.1" data-path="image-classifier.html"><a href="image-classifier.html#discover"><i class="fa fa-check"></i><b>22.1</b> Discover</a></li>
<li class="chapter" data-level="22.2" data-path="image-classifier.html"><a href="image-classifier.html#setup"><i class="fa fa-check"></i><b>22.2</b> Setup</a></li>
<li class="chapter" data-level="22.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>22.3</b> JavaScript</a></li>
<li class="chapter" data-level="22.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>22.4</b> Input Handler</a></li>
</ul></li>
<li class="chapter" data-level="23" data-path="progress-bar.html"><a href="progress-bar.html"><i class="fa fa-check"></i><b>23</b> Progress Bar</a>
<ul>
<li class="chapter" data-level="23.1" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>23.1</b> R code</a></li>
<li class="chapter" data-level="23.2" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>23.2</b> JavaScript code</a></li>
<li class="chapter" data-level="23.3" data-path="progress-bar.html"><a href="progress-bar.html#events"><i class="fa fa-check"></i><b>23.3</b> Events</a></li>
</ul></li>
<li class="part"><span><b>VII Closing Remarks</b></span></li>
<li class="chapter" data-level="24" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>24</b> Conclusion</a>
<ul>
<li class="chapter" data-level="24.1" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>24.1</b> Performances</a></li>
<li class="chapter" data-level="24.2" data-path="conclusion.html"><a href="conclusion.html#road-ahead"><i class="fa fa-check"></i><b>24.2</b> Road ahead</a>
<ul>
<li class="chapter" data-level="24.2.1" data-path="conclusion.html"><a href="conclusion.html#computation"><i class="fa fa-check"></i><b>24.2.1</b> Computation</a></li>
<li class="chapter" data-level="24.2.2" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>24.2.2</b> Shiny</a></li>
<li class="chapter" data-level="24.2.3" data-path="overview.html"><a href="overview.html#htmlwidgets"><i class="fa fa-check"></i><b>24.2.3</b> htmlwidgets</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="cookies" class="section level1" number="17">
<h1><span class="header-section-number">Chapter 17</span> Cookies</h1>
<p>In this chapter we scout yet another great example of how JavaScript can enhance shiny applications. We use an HTTP cookie, a small piece of data sent from a application and stored in the user’s web browser, to track users returning to a shiny application.</p>
<p>The application will prompt users to input their name, this will be stored in a cookie so that on their next visit they are welcomed to the app with a personalised message. Cookies are natively supported by web browsers and JavaScript, though we will use a library which greatly eases their handling: <a href="https://github.com/js-cookie/js-cookie">js-cookie</a>.</p>
<div id="discover-js-cookie" class="section level2" number="17.1">
<h2><span class="header-section-number">17.1</span> Discover js-cookie</h2>
<p>The library is at its core very straightforward, it exports a <code>Cookie</code> object from which one can access the <code>set</code>, <code>get</code>, and <code>remove</code> methods.</p>
<div class="sourceCode" id="cb364"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb364-1"><a href="cookies.html#cb364-1"></a><span class="co">// set a cookie</span></span>
<span id="cb364-2"><a href="cookies.html#cb364-2"></a>Cookies<span class="op">.</span><span class="fu">set</span>(<span class="st">&#39;name&#39;</span><span class="op">,</span> <span class="st">&#39;value&#39;</span>)</span>
<span id="cb364-3"><a href="cookies.html#cb364-3"></a></span>
<span id="cb364-4"><a href="cookies.html#cb364-4"></a><span class="co">// get cookies</span></span>
<span id="cb364-5"><a href="cookies.html#cb364-5"></a>Cookies<span class="op">.</span><span class="fu">get</span>()<span class="op">;</span></span>
<span id="cb364-6"><a href="cookies.html#cb364-6"></a></span>
<span id="cb364-7"><a href="cookies.html#cb364-7"></a><span class="co">// remove a cookie</span></span>
<span id="cb364-8"><a href="cookies.html#cb364-8"></a>Cookies<span class="op">.</span><span class="fu">remove</span>(<span class="st">&#39;name&#39;</span>)<span class="op">;</span></span></code></pre></div>
<p>There is also the possibility to pass additional options when defining the cookie, such as how long it is valid for, but we won’t explore these here.</p>
</div>
<div id="setup-cookies-project" class="section level2" number="17.2">
<h2><span class="header-section-number">17.2</span> Setup Cookies Project</h2>
<p>Then again, it starts with the creation of a directory where we’ll place a JavaScript file containing the message handlers, we won’t download the dependency and use the CDN instead but feel free to do differently.</p>
<div class="sourceCode" id="cb365"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb365-1"><a href="cookies.html#cb365-1"></a><span class="kw">dir.create</span>(<span class="st">&quot;www&quot;</span>)</span>
<span id="cb365-2"><a href="cookies.html#cb365-2"></a><span class="kw">file.create</span>(<span class="st">&quot;www/script.js&quot;</span>)</span></code></pre></div>
<p>We then lay down the skeleton of the application which features a text input to capture the name of the user, a button to save the cookie in their browsers, another to remove it and finally a dynamic output that will display the personalised message.</p>
<div class="sourceCode" id="cb366"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb366-1"><a href="cookies.html#cb366-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb366-2"><a href="cookies.html#cb366-2"></a></span>
<span id="cb366-3"><a href="cookies.html#cb366-3"></a><span class="kw">addResourcePath</span>(<span class="st">&quot;www&quot;</span>, <span class="st">&quot;www&quot;</span>)</span>
<span id="cb366-4"><a href="cookies.html#cb366-4"></a></span>
<span id="cb366-5"><a href="cookies.html#cb366-5"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb366-6"><a href="cookies.html#cb366-6"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb366-7"><a href="cookies.html#cb366-7"></a>    tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb366-8"><a href="cookies.html#cb366-8"></a>      <span class="dt">src =</span> <span class="kw">paste0</span>(</span>
<span id="cb366-9"><a href="cookies.html#cb366-9"></a>        <span class="st">&quot;https://cdn.jsdelivr.net/npm/js-cookie@rc/&quot;</span>,</span>
<span id="cb366-10"><a href="cookies.html#cb366-10"></a>        <span class="st">&quot;dist/js.cookie.min.js&quot;</span></span>
<span id="cb366-11"><a href="cookies.html#cb366-11"></a>      )</span>
<span id="cb366-12"><a href="cookies.html#cb366-12"></a>    ),</span>
<span id="cb366-13"><a href="cookies.html#cb366-13"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;www/script.js&quot;</span>)</span>
<span id="cb366-14"><a href="cookies.html#cb366-14"></a>  ),</span>
<span id="cb366-15"><a href="cookies.html#cb366-15"></a>  <span class="kw">textInput</span>(<span class="st">&quot;name_set&quot;</span>, <span class="st">&quot;What is your name?&quot;</span>),</span>
<span id="cb366-16"><a href="cookies.html#cb366-16"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;save&quot;</span>, <span class="st">&quot;Save cookie&quot;</span>),</span>
<span id="cb366-17"><a href="cookies.html#cb366-17"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;remove&quot;</span>, <span class="st">&quot;remove cookie&quot;</span>),</span>
<span id="cb366-18"><a href="cookies.html#cb366-18"></a>  <span class="kw">uiOutput</span>(<span class="st">&quot;name_get&quot;</span>)</span>
<span id="cb366-19"><a href="cookies.html#cb366-19"></a>)</span>
<span id="cb366-20"><a href="cookies.html#cb366-20"></a></span>
<span id="cb366-21"><a href="cookies.html#cb366-21"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb366-22"><a href="cookies.html#cb366-22"></a></span>
<span id="cb366-23"><a href="cookies.html#cb366-23"></a>}</span>
<span id="cb366-24"><a href="cookies.html#cb366-24"></a></span>
<span id="cb366-25"><a href="cookies.html#cb366-25"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
</div>
<div id="javascript-cookies" class="section level2" number="17.3">
<h2><span class="header-section-number">17.3</span> JavaScript Cookies</h2>
<p>First we define a JavaScript function that retrieves the cookies and sets the result as an input named <code>cookies</code>. The reason we do so is simply because we will have to execute this in multiple places, this will become clearer in just a second.</p>
<div class="sourceCode" id="cb367"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb367-1"><a href="cookies.html#cb367-1"></a><span class="co">// script.js</span></span>
<span id="cb367-2"><a href="cookies.html#cb367-2"></a><span class="kw">function</span> <span class="fu">getCookies</span>(){</span>
<span id="cb367-3"><a href="cookies.html#cb367-3"></a>  <span class="kw">var</span> res <span class="op">=</span> Cookies<span class="op">.</span><span class="fu">get</span>()<span class="op">;</span></span>
<span id="cb367-4"><a href="cookies.html#cb367-4"></a>  Shiny<span class="op">.</span><span class="fu">setInputValue</span>(<span class="st">&#39;cookies&#39;</span><span class="op">,</span> res)<span class="op">;</span></span>
<span id="cb367-5"><a href="cookies.html#cb367-5"></a>}</span></code></pre></div>
<p>Then we define two message handlers, one that sets the cookie and another that removes it. Note that both of them run the <code>getCookies</code> function defined previously after they are done with their respective operations. The reason this is done is that we need the input to be updated with the new values after it is set and after it is removed. Otherwise setting or removing the cookie will leave the actual input value untouched and the result of the operation (setting or removing the cookie) will not be captured server-side.</p>
<div class="sourceCode" id="cb368"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb368-1"><a href="cookies.html#cb368-1"></a><span class="co">// script.js</span></span>
<span id="cb368-2"><a href="cookies.html#cb368-2"></a>Shiny<span class="op">.</span><span class="fu">addCustomMessageHandler</span>(<span class="st">&#39;cookie-set&#39;</span><span class="op">,</span> <span class="kw">function</span>(msg){</span>
<span id="cb368-3"><a href="cookies.html#cb368-3"></a>  Cookies<span class="op">.</span><span class="fu">set</span>(msg<span class="op">.</span><span class="at">name</span><span class="op">,</span> msg<span class="op">.</span><span class="at">value</span>)<span class="op">;</span></span>
<span id="cb368-4"><a href="cookies.html#cb368-4"></a>  getCookies()<span class="op">;</span></span>
<span id="cb368-5"><a href="cookies.html#cb368-5"></a>})</span>
<span id="cb368-6"><a href="cookies.html#cb368-6"></a></span>
<span id="cb368-7"><a href="cookies.html#cb368-7"></a>Shiny<span class="op">.</span><span class="fu">addCustomMessageHandler</span>(<span class="st">&#39;cookie-remove&#39;</span><span class="op">,</span> <span class="kw">function</span>(msg){</span>
<span id="cb368-8"><a href="cookies.html#cb368-8"></a>  Cookies<span class="op">.</span><span class="fu">remove</span>(msg<span class="op">.</span><span class="at">name</span>)<span class="op">;</span></span>
<span id="cb368-9"><a href="cookies.html#cb368-9"></a>  getCookies()<span class="op">;</span></span>
<span id="cb368-10"><a href="cookies.html#cb368-10"></a>})</span></code></pre></div>
<p>One more thing needs to be implemented JavaScript-side. The point of using the cookie is that when users comes back to the shiny app, even days later, they are presented with the personalised welcome message, this implies that when they open the application the input value is defined. Therefore, <code>getCookies</code> must at launch. One could be tempted to place it at the top of the JavaScript file so that it runs when it is imported but the issue there is that it will run too soon, it will run the shiny input is not yet available and fail to set it. Consequently, we instead observe the <code>shiny:connected</code> event, which is fired when the initial connection to the server is established.</p>
<div class="sourceCode" id="cb369"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb369-1"><a href="cookies.html#cb369-1"></a><span class="co">// script.js</span></span>
<span id="cb369-2"><a href="cookies.html#cb369-2"></a>$(<span class="bu">document</span>)<span class="op">.</span><span class="fu">on</span>(<span class="st">&#39;shiny:connected&#39;</span><span class="op">,</span> <span class="kw">function</span>(ev){</span>
<span id="cb369-3"><a href="cookies.html#cb369-3"></a>  getCookies()<span class="op">;</span></span>
<span id="cb369-4"><a href="cookies.html#cb369-4"></a>})</span></code></pre></div>
</div>
<div id="r-code-for-cookies" class="section level2" number="17.4">
<h2><span class="header-section-number">17.4</span> R Code for Cookies</h2>
<p>Then it’s a matter a completing the shiny server which was left empty. We add an <code>observeEvent</code> on the save button where we check that a name has actually been typed in the text box before saving the cookie. There is another similar observer on the remove button. The <code>renderUI</code> expression checks that the cookie has been set and displays a message accordingly.</p>
<div class="sourceCode" id="cb370"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb370-1"><a href="cookies.html#cb370-1"></a><span class="kw">library</span>(shiny)</span>
<span id="cb370-2"><a href="cookies.html#cb370-2"></a></span>
<span id="cb370-3"><a href="cookies.html#cb370-3"></a><span class="kw">addResourcePath</span>(<span class="st">&quot;www&quot;</span>, <span class="st">&quot;www&quot;</span>)</span>
<span id="cb370-4"><a href="cookies.html#cb370-4"></a></span>
<span id="cb370-5"><a href="cookies.html#cb370-5"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb370-6"><a href="cookies.html#cb370-6"></a>  tags<span class="op">$</span><span class="kw">head</span>(</span>
<span id="cb370-7"><a href="cookies.html#cb370-7"></a>    tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb370-8"><a href="cookies.html#cb370-8"></a>      <span class="dt">src =</span> <span class="kw">paste0</span>(</span>
<span id="cb370-9"><a href="cookies.html#cb370-9"></a>        <span class="st">&quot;https://cdn.jsdelivr.net/npm/js-cookie@rc/&quot;</span>,</span>
<span id="cb370-10"><a href="cookies.html#cb370-10"></a>        <span class="st">&quot;dist/js.cookie.min.js&quot;</span></span>
<span id="cb370-11"><a href="cookies.html#cb370-11"></a>      )</span>
<span id="cb370-12"><a href="cookies.html#cb370-12"></a>    ),</span>
<span id="cb370-13"><a href="cookies.html#cb370-13"></a>    tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;www/script.js&quot;</span>)</span>
<span id="cb370-14"><a href="cookies.html#cb370-14"></a>  ),</span>
<span id="cb370-15"><a href="cookies.html#cb370-15"></a>  <span class="kw">textInput</span>(<span class="st">&quot;name_set&quot;</span>, <span class="st">&quot;What is your name?&quot;</span>),</span>
<span id="cb370-16"><a href="cookies.html#cb370-16"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;save&quot;</span>, <span class="st">&quot;Save cookie&quot;</span>),</span>
<span id="cb370-17"><a href="cookies.html#cb370-17"></a>  <span class="kw">actionButton</span>(<span class="st">&quot;remove&quot;</span>, <span class="st">&quot;remove cookie&quot;</span>),</span>
<span id="cb370-18"><a href="cookies.html#cb370-18"></a>  <span class="kw">uiOutput</span>(<span class="st">&quot;name_get&quot;</span>)</span>
<span id="cb370-19"><a href="cookies.html#cb370-19"></a>)</span>
<span id="cb370-20"><a href="cookies.html#cb370-20"></a></span>
<span id="cb370-21"><a href="cookies.html#cb370-21"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output, session){</span>
<span id="cb370-22"><a href="cookies.html#cb370-22"></a></span>
<span id="cb370-23"><a href="cookies.html#cb370-23"></a>  <span class="co"># save</span></span>
<span id="cb370-24"><a href="cookies.html#cb370-24"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>save, {</span>
<span id="cb370-25"><a href="cookies.html#cb370-25"></a>    msg &lt;-<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb370-26"><a href="cookies.html#cb370-26"></a>      <span class="dt">name =</span> <span class="st">&quot;name&quot;</span>, <span class="dt">value =</span> input<span class="op">$</span>name_set</span>
<span id="cb370-27"><a href="cookies.html#cb370-27"></a>    )</span>
<span id="cb370-28"><a href="cookies.html#cb370-28"></a></span>
<span id="cb370-29"><a href="cookies.html#cb370-29"></a>    <span class="cf">if</span>(input<span class="op">$</span>name_set <span class="op">!=</span><span class="st"> &quot;&quot;</span>)</span>
<span id="cb370-30"><a href="cookies.html#cb370-30"></a>      session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&quot;cookie-set&quot;</span>, msg)</span>
<span id="cb370-31"><a href="cookies.html#cb370-31"></a>  })</span>
<span id="cb370-32"><a href="cookies.html#cb370-32"></a></span>
<span id="cb370-33"><a href="cookies.html#cb370-33"></a>  <span class="co"># delete</span></span>
<span id="cb370-34"><a href="cookies.html#cb370-34"></a>  <span class="kw">observeEvent</span>(input<span class="op">$</span>remove, {</span>
<span id="cb370-35"><a href="cookies.html#cb370-35"></a>    msg &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">name =</span> <span class="st">&quot;name&quot;</span>)</span>
<span id="cb370-36"><a href="cookies.html#cb370-36"></a>    session<span class="op">$</span><span class="kw">sendCustomMessage</span>(<span class="st">&quot;cookie-remove&quot;</span>, msg)</span>
<span id="cb370-37"><a href="cookies.html#cb370-37"></a>  })</span>
<span id="cb370-38"><a href="cookies.html#cb370-38"></a></span>
<span id="cb370-39"><a href="cookies.html#cb370-39"></a>  <span class="co"># output if cookie is specified</span></span>
<span id="cb370-40"><a href="cookies.html#cb370-40"></a>  output<span class="op">$</span>name_get &lt;-<span class="st"> </span><span class="kw">renderUI</span>({</span>
<span id="cb370-41"><a href="cookies.html#cb370-41"></a>    <span class="cf">if</span>(<span class="op">!</span><span class="kw">is.null</span>(input<span class="op">$</span>cookies<span class="op">$</span>name))</span>
<span id="cb370-42"><a href="cookies.html#cb370-42"></a>      <span class="kw">h3</span>(<span class="st">&quot;Hello,&quot;</span>, input<span class="op">$</span>cookies<span class="op">$</span>name)</span>
<span id="cb370-43"><a href="cookies.html#cb370-43"></a>    <span class="cf">else</span></span>
<span id="cb370-44"><a href="cookies.html#cb370-44"></a>      <span class="kw">h3</span>(<span class="st">&quot;Who are you?&quot;</span>)</span>
<span id="cb370-45"><a href="cookies.html#cb370-45"></a>  })</span>
<span id="cb370-46"><a href="cookies.html#cb370-46"></a></span>
<span id="cb370-47"><a href="cookies.html#cb370-47"></a>}</span>
<span id="cb370-48"><a href="cookies.html#cb370-48"></a></span>
<span id="cb370-49"><a href="cookies.html#cb370-49"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/shiny-cookies-2.png" alt="" />
<p class="caption">Shiny cookies</p>
</div>
<p>Run the application and save your name. You can then refresh the application and the welcome message will display your name. You can even kill the server entirely and re-run the app, the welcome message will still display!</p>

</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="custom-inputs.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="widgets-with-shiny.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/4-17-shiny-cookies.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
